/**
 * Copyright 2007 Igor Chaves Cananéa
 *
 * This file is part of PBSFW
 *
 * PBSFW is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * PBSFW is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef _SEQUENCE_REPORTER_H_
#define _SEQUENCE_REPORTER_H_

#include "defines.h"
#include "reporter.h"
#include "statistic.h"
#include "simulatorinterface.h"
using namespace statistic;

namespace pbsfw {
    class SequenceReporter : public Reporter {
        private:
            map<Property*, vector<Statistic*> > data;
            map<Property*, uint> maxSamples;
            map<Property*, uint> currentSamples;
            map<Property*, uint> stopSize;
            map<Property*, vector<simtime_t> > times;

        protected:
            void do_queryProperties(PropertyItem p) {
                map<Property*, vector<Statistic*> >::iterator itr
                    = this->data.find(p);

                if (this->maxSamples.find(p) == this->maxSamples.end()) {
                    this->maxSamples[p] = 0;
                    this->stopSize[p] = 0xFFFFFFFF;
                }

                if (this->currentSamples[p] >= this->maxSamples[p]) {
                    this->data[p].push_back(new Statistic());
                    this->times[p].push_back(simulator.now());
                }

                this->data[p][this->currentSamples[p]]->addObservation(p->getValue());
                ++this->currentSamples[p];
            }

        public:
            SequenceReporter(FILE *output, simtime_t interval)
                : Reporter(output, interval) {
            }

            ~SequenceReporter() {
                map<Property*, vector<Statistic*> >::iterator itr = this->data.begin();
                map<Property*, vector<Statistic*> >::iterator end = this->data.end();

                while (itr != end) {
                    vector<Statistic*> &v = itr->second;
                    uint size = v.size();
                    for (uint i = 0; i < size; ++i) {
                        delete v[i];
                    }
                    ++itr;
                }
                this->data.clear();
                this->maxSamples.clear();
                this->currentSamples.clear();
                this->stopSize.clear();
                this->times.clear();
            }

            void reset();
            void simulationEnd();
    };
};

#endif
